package com.lancoo.answer.view.fragment.translate;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.ColorDrawable;
import android.text.Editable;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.style.LeadingMarginSpan;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.RecyclerView;

import com.lancoo.answer.R;
import com.lancoo.answer.model.ConstantBean;
import com.lancoo.answer.model.bean.Child;
import com.lancoo.answer.model.bean.ItemAsk;
import com.lancoo.answer.model.entity.TaskControlBean;
import com.lancoo.answer.util.DpUtils;
import com.lancoo.answer.util.EditTextInputUtil;
import com.lancoo.answer.util.ExamFontSizeAdjustUtils;
import com.lancoo.answer.util.NetWorkTools;
import com.lancoo.answer.util.paperUtils.FragmentCommunicationUtils;
import com.lancoo.answer.widget.WaveView;
import com.lancoo.answer.widget.combinationView.QueseBodyView;
import com.rxjava.rxlife.RxLife;
import com.stkouyu.LancooSpeechRecognitionManager;
import com.stkouyu.listener.OnLancooSpeechRecognitionListener;

import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by pengmi on 2021/12/10 11:24
 * Description:
 */
public class TranslateChapterAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private final List<ItemAsk> itemAskList;
    private OnStuAnswerUpdateCallBack callBack;
    private final int distinguishType;
    private final String TAG_LOCAL_UPDATE="local_update";
    private final String TAG_CLOSE_AUDIO="audio_answer_close";
    private final String TAG_MARK_QUESTION="mark_question";
    private final Child child;

    public TranslateChapterAdapter(List<ItemAsk> itemAskList, int distinguishType, Child child) {
        this.itemAskList = itemAskList;
        this.distinguishType=distinguishType;
        this.child=child;
    }

    public void setCallBack(OnStuAnswerUpdateCallBack callBack){
        this.callBack=callBack;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View inflater=LayoutInflater.from(parent.getContext()).inflate(R.layout.ev_item_tanslate_chapter_sentence_answer,parent,false);
        return new VH(inflater,callBack,distinguishType,child);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        VH vh= (VH) holder;
        vh.initData(position,itemAskList.get(position));
//        vh.setIsRecyclable(false);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull List<Object> payloads) {
        super.onBindViewHolder(holder, position, payloads);
        if(payloads.contains(TAG_LOCAL_UPDATE)){
            Log.e("eee","去更新啦");
            VH vh= (VH) holder;
            vh.updateFocus();
        }else if(payloads.contains(TAG_CLOSE_AUDIO)){
            VH vh= (VH) holder;
            vh.closeAudioAnswer();
        }else if(payloads.contains(TAG_MARK_QUESTION)){
            VH vh= (VH) holder;
            vh.markQuestion();
        }else {
            super.onBindViewHolder(holder,position,payloads);
        }
    }

    @Override
    public int getItemCount() {
        return itemAskList==null?0:itemAskList.size();
    }

    public static class VH extends RecyclerView.ViewHolder implements
            TextWatcher,View.OnTouchListener,View.OnClickListener {

        private ItemAsk itemAsk;
        private final EditText editText;
        private WaveView waveView;
        private PopupWindow popupWindow;
        private final OnStuAnswerUpdateCallBack callBack;
        private final int distinguishType;
        private final TextView tv_hint;
        private TextView tv_index;
        private int selecIndex=-1;
        private final Child child;
        private final String tag="\t";


        public VH(@NonNull View itemView,OnStuAnswerUpdateCallBack callBack,int distinguishType,Child child) {
            super(itemView);
            this.callBack=callBack;
            this.distinguishType=distinguishType;
            this.child=child;
            editText = itemView.findViewById(R.id.edittext);
            tv_hint = itemView.findViewById(R.id.tv_hint);
            editText.addTextChangedListener(this);
            editText.setOnClickListener(this);
            EditTextInputUtil.disableCopyAndPaste(editText);
            View img_microphone=itemView.findViewById(R.id.img_microphone);
            img_microphone.setOnTouchListener(this);
            editText.setOnFocusChangeListener((v, hasFocus) -> {
                if(hasFocus){
                    int adapterPosition = getBindingAdapterPosition();
                    if (TextUtils.isEmpty(editText.getText().toString()) ||
                            editText.getText().toString().equals(tag)){
                        tv_hint.setVisibility(View.VISIBLE);
                    }
                    if(callBack==null||adapterPosition<0){
                        return;
                    }
                    callBack.onClickItemIndex(adapterPosition);
                }else {
                    if (TextUtils.isEmpty(editText.getText().toString()) || editText.getText().toString().equals(tag)){
                        tv_hint.setVisibility(View.VISIBLE);
                    }
                }
            });
            TaskControlBean taskControlBean = ConstantBean.Companion.getTaskControlBean();
            if(taskControlBean!=null&&taskControlBean.getEnableAnwer()==0){//禁止作答
                editText.setEnabled(false);
                img_microphone.setEnabled(false);
            }
        }

        private void initData(int position,ItemAsk itemAsk){
            //        private final String tag=" ";
            this.itemAsk=itemAsk;
            tv_index = itemView.findViewById(R.id.tv_index);
            Log.e("TranslateChapterAdapter","initData"+itemAsk.getAskTip());
            tv_index.setText(itemAsk.getAskTip());
            editText.clearComposingText();
            String stuAns=TextUtils.isEmpty(itemAsk.getStuAnswer())?" ":itemAsk.getStuAnswer();
            editText.clearComposingText();
            editText.setText(stuAns);
            QueseBodyView queseBodyView=itemView.findViewById(R.id.quese_body_view);
            queseBodyView.setEnableShowChildAsk(false);
            queseBodyView.setVisibility(position==0?View.VISIBLE:View.GONE);
            queseBodyView.initData(child);
            queseBodyView.adjustFontSize();
            selecIndex=itemAsk.getFouceIndex();
            ExamFontSizeAdjustUtils.adjustTextViewFontSize(editText,13);
            ExamFontSizeAdjustUtils.adjustTextViewFontSize(tv_hint,14);
            ExamFontSizeAdjustUtils.adjustTextViewFontSize(tv_index,14);


        }

        private void updateFocus(){
            Log.e("eee","updateFocus:"+selecIndex);
            if(editText!=null){
                if(selecIndex!=-1){
                    editText.setSelection(Math.min(editText.getText().toString().length(), selecIndex));
                    editText.requestFocus();
                }
            }
        }

        private void closeAudioAnswer(){
            if(popupWindow != null && popupWindow.isShowing()){
                LancooSpeechRecognitionManager.getInstance(itemView.getContext()).
                        stopSpeechRecognition(true);
                popupWindow.dismiss();
            }
        }

        private void markQuestion(){
            QueseBodyView queseBodyView=itemView.findViewById(R.id.quese_body_view);
            queseBodyView.markQuestion();
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            Log.e("eee","beforeTextChangedtest："+start+"=="+count+"=="+after+"str:"+s);
            Log.e("eee","111jinlaile index:"+editText.getSelectionStart());
            itemAsk.setFouceIndex(editText.getSelectionStart());

        }

        @Override
        public void onTextChanged(CharSequence s1, int start, int before, int count) {



        }

        @Override
        public void afterTextChanged(Editable s) {
            Log.e("eee","afterTextChanged："+s);
            if(!TextUtils.equals(itemAsk.getStuAnswer(),s.toString())){
                itemAsk.setStuAnswer(s.toString().replace(tag,"").trim());
                if(callBack!=null){
                    callBack.updateCallBack();
                }
            }
            int dp10= DpUtils.dip2px(tv_hint.getContext(),5);
            float length= tv_index.getPaint().measureText(itemAsk.getAskTip())+dp10;//+ralWidth- tv_index.getPaint().measureText(itemAsk.getAskTip());
            s.removeSpan(LeadingMarginSpan.class);
            LeadingMarginSpan[] spans = s.getSpans(0, s.length(), LeadingMarginSpan.class);
            if(spans.length>0){
                int index=0;
                for (LeadingMarginSpan span:spans){
                    int spanStart = s.getSpanStart(span);
                    int leadingMargin = span.getLeadingMargin(false);
                    Log.e("span",leadingMargin+","+index+"->"+spans.length+" spanStart:"+spanStart);
                    index++;
                    s.removeSpan(span);
                }
            }
            boolean isAddTr=spans.length==0||s.getSpanStart(spans[spans.length-1])!=0;
            if(isAddTr){
                if(TextUtils.isEmpty(s)){
                    s.append(" ");
                }
                LeadingMarginSpan[] spans1 = s.getSpans(0, s.length(), LeadingMarginSpan.class);
                if(spans1.length>0){
                    return;
                }
//                length+= tv_index.getPaint().measureText(" ");
                if(s.toString().startsWith(" ")){
                    Log.e("span","空格开头");
                }else {
                    Log.e("span","不是空格开头");
                    length+= tv_index.getPaint().measureText(" ");
                }
                s.setSpan(new LeadingMarginSpan.Standard((int)length,0),0,
                        TextUtils.isEmpty(s)?s.length():1,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            Log.e("eee","最终文本内容："+s);
            if (TextUtils.isEmpty(editText.getText().toString().trim())
                    || editText.getText().toString().equals(tag)){
                tv_hint.setVisibility(View.VISIBLE);
            }else{
                tv_hint.setVisibility(View.INVISIBLE);
            }
            Log.e("eee","end："+editText.getText());

        }

        private long subTime;
        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Context mContext=v.getContext();
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    subTime= System.currentTimeMillis();
                    startRecognition();
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                    FragmentCommunicationUtils.testEventBus();
                    editText.requestFocus();
                    editText.setFocusable(true);
                    return true;
                case MotionEvent.ACTION_UP:
                    if(NetWorkTools.isNetworkConnected(mContext)){
                        boolean isResult= System.currentTimeMillis()-subTime>=200;
                        stopRecognition(isResult);
                    }else{
                        stopRecognition(false);
                        Toast.makeText(mContext,"抱歉，当前网络不可用", Toast.LENGTH_SHORT).show();
                    }
                    return true;
                case MotionEvent.ACTION_CANCEL:
//                    stopRecognition(false);
                    return true;
            }
            return false;
        }


        private void startRecognition(){
            if (ActivityCompat.checkSelfPermission(itemView.getContext(), Manifest.permission.RECORD_AUDIO)
                    != PackageManager.PERMISSION_GRANTED) {
//            Toast.makeText(getApplicationContext(), "没有获取权限,请手动开启权限", Toast.LENGTH_SHORT).show();
                // 申请一个（或多个）权限，并提供用于回调返回的获取码（用户定义）
                String[] pressisionArray;
                try {
                    pressisionArray = new String[]{Manifest.permission.RECORD_AUDIO};
                    Log.e("eeee", "权限不足，请求响应");
                    ActivityCompat.requestPermissions( (Activity) itemView.getContext(), pressisionArray, 100);//,Manifest.permission.READ_PHONE_STATE
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e("eeee", "权限不足，error:"+e.toString());
                }
                return;
            }
            int adapterPosition = getBindingAdapterPosition();
            if(callBack!=null&&adapterPosition>=0){
                callBack.onClickItemIndex(adapterPosition);
            }
            showRecordPop();
            LancooSpeechRecognitionManager.getInstance(itemView.getContext())
                    .startSpeechRecognition(distinguishType, new OnLancooSpeechRecognitionListener() {
                        @Override
                        public void onSpeechRecognitionStart() {

                        }

                        @Override
                        public void onSpeechRecogniting(int vad_status, int sound_intensity) {
                            if(!itemView.isAttachedToWindow()){
                                return;
                            }
                            Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
                                        emitter.onNext(sound_intensity);
                                    })
                                    .subscribeOn(Schedulers.io())
                                    .observeOn(AndroidSchedulers.mainThread())
                                    .as(RxLife.as(itemView))
                                    .subscribe(o -> {
                                        if(waveView!=null){
                                            waveView.setVisibility(View.VISIBLE);
                                            waveView.addData((short)sound_intensity);
                                        }
                                    }, throwable -> {});

                        }

                        @Override
                        public void onSpeechRecognitionEnd(String recognitionSentence, String url) {
                            appendAnswer(recognitionSentence);
                        }

                        @Override
                        public void onSpeechRecognitionError(String error) {

                        }
                    });
        }

        private void stopRecognition(boolean isEnd){
            LancooSpeechRecognitionManager.getInstance(itemView.getContext()).stopSpeechRecognition(isEnd);
            if(popupWindow!=null&&popupWindow.isShowing()){
                popupWindow.dismiss();
            }
        }

        private void appendAnswer(String appendContent){
            if(!TextUtils.isEmpty(appendContent)){
                boolean isEndEmpty=appendContent.endsWith(" ");
                String substring = appendContent.substring(0, 1);
                String s = substring.toUpperCase();
                String ends=distinguishType==1?"。":".";
                appendContent=s+appendContent.substring(1,appendContent.length()-(isEndEmpty?1:0))+ends;
            }
            Editable text = editText.getText();
            if(TextUtils.isEmpty(text)){
                itemAsk.setStuAnswer(appendContent.replace(tag,""));
                editText.setSelection(editText.getText().length());
            }else{
                int selectionStart = editText.getSelectionStart();
                if(selectionStart>=0&&selectionStart<text.length()){
                    text.insert(selectionStart,appendContent);
                    editText.setSelection(selectionStart+appendContent.length());
                }else{
                    CharSequence charSequence = text.subSequence(text.length() - 1, text.length());
                    if (!TextUtils.equals(" ", charSequence)) {
                        text.append(" ");
                    }
                    text.append(appendContent);
                    editText.setSelection(text.length());
                }
                itemAsk.setStuAnswer(text.toString().replace(tag,""));
            }
        }

        private void showRecordPop(){
            @SuppressLint("InflateParams") View inflater= LayoutInflater.from(itemView.getContext()).inflate(R.layout.ev_layout_pop_recording,null);
            popupWindow = new PopupWindow(inflater,
                    RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
            popupWindow.setFocusable(false);
            popupWindow.setOutsideTouchable(false);
            popupWindow.setBackgroundDrawable(new ColorDrawable());
            popupWindow.showAtLocation(itemView, Gravity.CENTER,0,0);
            waveView = inflater.findViewById(R.id.waveview);
        }

        @Override
        public void onClick(View v) {
            int adapterPosition = getBindingAdapterPosition();
            Log.e("66666", "onClick: "+adapterPosition );
            if(callBack==null||adapterPosition<0){
                return;
            }
            Log.e("eee", "onClick selection: "+ editText.getSelectionStart() );
            selecIndex=editText.getSelectionStart();
            callBack.onClickItemIndex(adapterPosition);
        }
    }

    public interface OnStuAnswerUpdateCallBack{

        void updateCallBack();

        void onClickItemIndex(int itemIndex);
    }

    public void localUpdate(int position){
        notifyItemChanged(position,TAG_LOCAL_UPDATE);
    }


    /**
     * 关闭音频作答
     */
    public void closeAudioAnswer(int position){
        if(position >=itemAskList.size()){
            return;
        }
        notifyItemChanged(position,TAG_CLOSE_AUDIO);
    }

    public void markQuestion(){
        notifyItemChanged(0,TAG_MARK_QUESTION);
    }
}
